package com.tju.backend.resources.config.security.configSecurity;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.tju.backend.dao.sys_user.SysUserMapper;
import com.tju.backend.entity.SysMenu;
import com.tju.backend.entity.SysUser;
import com.tju.backend.resources.config.security.custom.MyaccessDeniedException;
import com.tju.backend.service.business.SysMenuService;
import com.tju.backend.utils.date.DateUtils;
import com.tju.backend.utils.redis.RedisService;
import com.tju.backend.utils.result.ResultEnum;
import com.tju.backend.utils.result.ResultUtil;
import com.tju.backend.utils.tool.Constants;
import com.tju.backend.utils.tool.EmptyUtils;
import com.tju.backend.utils.tool.Voucher;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 登录成功处理器
 *
 * @USER: CLS
 */
@Component
public class MyAuthenticationSuccessHandler extends JSONAuthentication implements AuthenticationSuccessHandler {

    @Autowired
    private SysMenuService menuService;

    @Autowired
    private RedisService redisService;

    @Autowired
    private SysUserMapper userMapper;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest request,
                                        HttpServletResponse response,
                                        Authentication authentication) throws IOException, ServletException {
        //取得账号信息
        UserDetails userDetails = (UserDetails) authentication.getPrincipal();
        SecurityContextHolder.getContext().setAuthentication(authentication);
        //取token
        //好的解决方案，登录成功后token存储到数据库中(缓存)
        //只要token还在过期内，不需要每次重新生成
        //先去缓存中找
        String token = (String) redisService.get(userDetails.getUsername());

        if (EmptyUtils.isEmpty(token)) {
            //如果token为空，则去创建一个新的token
            token = jwtTokenUtil.generateToken(userDetails);
            //把新的token存储到高速缓存中
            redisService.redisSetData(userDetails.getUsername(), token, DateUtils.msTurnSeconds(Constants.EXPIRATION_TIME));
        }

        //加载前端菜单
        List<SysMenu> menus = menuService.getMenusByUserName(userDetails.getUsername());
        Map<String, Object> map = new HashMap<>();
        //获取到用户名
        QueryWrapper<SysUser> wrapper = new QueryWrapper<>();
        wrapper.eq("login_name", userDetails.getUsername());
        SysUser user = userMapper.selectOne(wrapper);
        user.setId(null);
        user.setLoginPassword(null);
        Voucher voucher = new Voucher(token, redisService.getExpire(userDetails.getUsername(), null));
        userDetails.getAuthorities().forEach(u -> voucher.setAuth(String.valueOf(u)));
        map.put("user", user);
        map.put("menus", menus);
        map.put("voucher", voucher);

        //装入token和其它扩展的参数
        this.WriteJSON(request, response, ResultUtil.success(ResultEnum.SUCCESS, map));
    }

}
